/*
    YmsgIRC - Program enabling YMSG chat clients to use IRC
    Copyright (C) 2011 Crash Daemonicus ( crashenator -at- gmail.com )

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common.h"


/*
+Description:
	Forming the first 20 bytes of each packet is a header.
	Most usefully, the header communicates protocol information and the dynamic size of the content section of each packet.

	Most of the properties of the header are self-explanatory with the exception of VendorID and Status which are usually treated as case-specific.
	(Version and PacketType conditions respectively)
+About this implementation:
	This implements a packet as a Header object, and the field-data Contents (represented both as a string and a object containing Field objects)
	acquiring the total size of the packet as raw data and the acquisition of that raw data in a buffer are supported by methods.

	Note: YmsgItem is used as a field container for convenience reasons only.
	If you initialize with an Item, use a 0-typed one where applicable to prevent container-fields from being added during conversion. 
*/



#pragma pack(1)
struct tYmsgHead
{
    unsigned char signature[4];//"YMSG" - the protocol signature
    WORD version;//the YMSG protocol version (eg: 15,16,18,102)
    WORD vendorID;//usually this isn't required to be set except with versions above 100
    WORD contentLength;//length of the field-data forming the dynamic-sized content of the packet
    WORD type;//The type of packet; ie: the type of message,action, or event being communicated
    int status;//the packet status or possibly protocol state, case-specific for a few packets, but commonly 0 or 1 for client-sent/server-sent and -1 (0xFFFF) for Error.
    unsigned int sessionID;// a session-specific identifier given by a YMSG server during connection.  Client SID is required to match for subsequent packets. 
};


class YmsgHead
{
    public:
        tYmsgHead Dat, Ref;// Two headers purely for Raw data (Dat) and Display reference (Ref) purposes - the translate methods convert between the two
						   // `Ref` only exists because the byte-endianness the server uses does not match the architecture that this program is compiled for.
						   // The `Dat` (Data) header is what you should use when sending data to a client or server.
        bool      availDat,availRef;// whether header information is available for Data or Reference purposes. A translate() may help this condition.
        YmsgHead();
        void reset();// default initial conditions - currently just considers neither Dat or Ref available
        //void setDat(tYmsgHead pt);
        void setDat(const tYmsgHead& t); //copy a header over the Data header   - considers only Dat as "available" afterwards
        void setRef(const tYmsgHead& t); //"             over the Reference header  - considers only Ref as "available" afterwards
        void setDat(const tYmsgHead* t); //"                      Data (via pointer) - "             Dat  "
        void translate(tYmsgHead& t);//Translate a header between Data/Reference mode - these only exist because of byte order issues.
        void translate();//if either the Data or Reference header is available, translate it so both are available.
		void set(int typ,int len,int sta=1,int sid=0,int vid=0,int ver=16);//set Reference header values and translate the Data header automagically.
		void copySession(const YmsgHead& head);//copy the Dat and Ref versions of the SessionID to this object from a different one
        void print();//debug function to print header information  (TODO: rename to debug() )
};